import os
from flask import Blueprint, request, current_app, jsonify, send_from_directory
from werkzeug.utils import secure_filename
from ..api.auth import login_required
from ..utils.ip import get_client_ip
from ..utils.file_utils import get_file_type, check_file_type, get_mime_type
from ..api.system import record_upload
from datetime import datetime
import json
import mimetypes

upload_bp = Blueprint('upload', __name__)

ALLOWED_EXTENSIONS = {'txt', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'}

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@upload_bp.route('/', methods=['POST'])
@login_required
def upload_file():
    if 'file' not in request.files:
        return jsonify({'error': '没有文件被上传'}), 400
    
    file = request.files['file']
    if file.filename == '':
        return jsonify({'error': '没有选择文件'}), 400
        
    if file and allowed_file(file.filename):
        # 确保文件名是安全的，但保留完整的文件名
        original_filename = file.filename
        secure_name = secure_filename(original_filename)
        
        # 确保文件扩展名正确
        if '.' not in secure_name:
            # 尝试从MIME类型推断扩展名
            mime_type = file.content_type
            ext = mimetypes.guess_extension(mime_type)
            if ext:
                secure_name = f"{secure_name}{ext}"
            else:
                # 无法推断扩展名时，检查原始文件名
                if '.' in original_filename:
                    ext = original_filename.rsplit('.', 1)[1].lower()
                    if ext in ALLOWED_EXTENSIONS:
                        secure_name = f"{secure_name}.{ext}"
        
        # 获取上传者IP信息
        ip_info = get_client_ip()
        
        # 获取文件大小（字节数）
        file.seek(0, os.SEEK_END)
        file_size = file.tell()
        file.seek(0)  # 重置文件指针到开始位置
        
        # 获取文件类型
        file_type = get_file_type(secure_name)
        mime_type = get_mime_type(secure_name)
        
        # 创建文件信息
        file_info = {
            'filename': secure_name,
            'original_name': original_filename,  # 存储原始文件名
            'upload_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'uploader_ip': ip_info['ip'],
            'uploader_location': ip_info['location'] if 'location' in ip_info else '未知',
            'size': file_size,  # 保存原始字节数
            'file_type': file_type,  # 保存文件类型
            'mime_type': mime_type  # 保存MIME类型
        }
        
        try:
            # 保存文件
            file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], secure_name))
            
            # 保存文件信息到数据库或JSON文件
            save_file_info(file_info)
            
            # 记录上传事件
            record_upload(original_filename, ip_info['ip'])
            
            return jsonify({
                'message': '文件上传成功',
                'file_info': file_info
            }), 200
        except Exception as e:
            return jsonify({'error': f'文件保存失败: {str(e)}'}), 500
    
    return jsonify({'error': '不允许的文件类型'}), 400

def save_file_info(file_info):
    """保存文件信息到JSON文件"""
    info_file = os.path.join(current_app.config['UPLOAD_FOLDER'], 'file_info.json')
    file_records = []
    
    # 读取现有记录
    if os.path.exists(info_file):
        with open(info_file, 'r', encoding='utf-8') as f:
            try:
                file_records = json.load(f)
            except json.JSONDecodeError:
                file_records = []
    
    # 添加新记录
    file_records.append(file_info)
    
    # 保存更新后的记录
    with open(info_file, 'w', encoding='utf-8') as f:
        json.dump(file_records, f, ensure_ascii=False, indent=4)

@upload_bp.route('/files')
@login_required
def list_files():
    """获取文件列表及其信息"""
    files = []
    info_file = os.path.join(current_app.config['UPLOAD_FOLDER'], 'file_info.json')
    
    # 读取文件信息
    if os.path.exists(info_file):
        with open(info_file, 'r', encoding='utf-8') as f:
            try:
                files = json.load(f)
            except json.JSONDecodeError:
                files = []
    
    return jsonify(files)

@upload_bp.route('/check_space')
@login_required
def check_space():
    upload_dir = current_app.config['UPLOAD_FOLDER']
    total_size = sum(os.path.getsize(os.path.join(upload_dir, f)) 
                    for f in os.listdir(upload_dir) 
                    if os.path.isfile(os.path.join(upload_dir, f)))
                    
    return jsonify({
        'total_size': total_size,
        'total_files': len(os.listdir(upload_dir))
    }) 